package com.sz.app.edi.rest.edi.fee;

import com.sz.app.edi.rest.edi.base.EventBody;
import com.sz.app.edi.rest.edi.base.EventHead;
import com.sz.app.edi.rest.edi.base.LogisticsRequest;
import com.sz.app.edi.rest.edi.base.Response;
import com.sz.app.edi.rest.edi.fee.dto.ProductCalcDto;
import com.sz.app.edi.rest.edi.fee.dto.ServiceFeeDto;
import com.sz.app.edi.rest.edi.fee.dto.CalcDto;
import com.sz.biz.app.web.BaseController;
import com.sz.biz.common.base.entity.FeeType;
import com.sz.biz.common.base.service.FeeTypeService;
import com.sz.biz.common.constants.SystemConstants;
import com.sz.biz.common.customer.entity.CusCustomer;
import com.sz.biz.common.customer.service.CustomerService;
import com.sz.biz.logistics.billing.dto.QuotationCalcObject;
import com.sz.biz.logistics.billing.dto.QuotationCalcResult;
import com.sz.biz.logistics.billing.service.QuotationCalcService;
import com.sz.biz.logistics.core.entity.ProductGroup;
import com.sz.biz.logistics.core.service.ProductGroupService;
import com.sz.common.base.exception.BizException;
import com.sz.common.base.utils.EntityUtils;
import com.sz.common.base.utils.JsonUtils;
import com.sz.common.core.system.service.SysDictService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ExecutionException;

/**
 * Function: EDI-费用. <br>
 * Date: 2017年12月26日 17:25 <br>
 * Author: wentao.chang
 */
@RestController
@RequestMapping("${out}/fee")
@Api(description = " ", tags = "052-000、EDI-费用")
public class FeeController extends BaseController {
    @Autowired
    private QuotationCalcService quotationCalcService;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private SysDictService sysDictService;

    @Autowired
    private FeeTypeService feeTypeService;

    @Autowired
    private ProductGroupService productGroupService;

    @ApiOperation(value = "运费试算", notes = "运费试算")
    @RequestMapping(value = "/", method = {RequestMethod.POST})
    public Response feeCalc(HttpServletRequest request,
                            @RequestBody @ApiParam(value = "计费对象", required = true) LogisticsRequest logisticsRequest)
            throws ExecutionException, InterruptedException {

        EventHead head = logisticsRequest.getEventHead();
        EventBody body = logisticsRequest.getEventBody();

        ProductCalcDto dto = JsonUtils.toObject(JsonUtils.toJSONString(body.getData()), ProductCalcDto.class);

        int customerId = Integer.parseInt(request.getAttribute("bizId").toString());
        CusCustomer cusCustomer = customerService.findShortById(customerId);

        List<CalcDto> dtos = new ArrayList<>();
        QuotationCalcObject calcResult = quotationCalcService.calcProductSalePrice(customerId, null,
                null, new Date(), dto.getCargoTypeCode(), cusCustomer.getTradingCurrency(),
                dto.getWeight(), dto.getVolume()==null?BigDecimal.ZERO:dto.getVolume(),
                dto.getUnitCode(), BigDecimal.ZERO,
                dto.getFromCountry(), dto.getFromProvince(), dto.getFromCity(),
                dto.getFromArea(), dto.getFromStreet(), dto.getFromPostcode(),
                dto.getFromCountry(), dto.getFromProvince(), dto.getFromCity(),
                dto.getFromArea(), dto.getFromStreet(), dto.getFromPostcode(),
                dto.getToCountry(), dto.getToProvince(), dto.getToCity(),
                dto.getToArea(), dto.getToStreet(), null,
                0, 0, Collections.singletonList(""), true, true, SystemConstants.SystemType.CUSTOMER);

        //组装页面的对象
        if (calcResult != null && !CollectionUtils.isEmpty(calcResult.getResult())) {
            //产品预估时效
            Map<String, String> estimatedMap = sysDictService.findMapByCatalog("biz.product.estimated.unit");

            List<Integer> feeTypeIds = EntityUtils.getIntPropListFromBeans(calcResult.getResult(), "feeTypeId");
            //费用类型
            List<FeeType> feeTypes = feeTypeService.findByIds(feeTypeIds);
            Map<String, FeeType> feeTypeMap = EntityUtils.getStringKeyMapFromBeans(feeTypes, "id");
            //产品组
            List<ProductGroup> pgs = productGroupService.list();
            Map<String, ProductGroup> pgMap = EntityUtils.getStringKeyMapFromBeans(pgs, "id");

            Map<String, CalcDto> results = new HashMap<>(16);
            for (QuotationCalcResult result : calcResult.getResult()) {
                // 货币与选择的货币不一致，过滤
                if (!result.getCurrencyCode().equals(cusCustomer.getTradingCurrency())) {
                    continue;
                }

                CalcDto calcDto = results.get(result.getQuotationId() + "");
                if (calcDto == null) {
                    calcDto = new CalcDto();

                    calcDto.setProductUid(result.getProductUid());
                    calcDto.setProductName(result.getProductName());
                    calcDto.setCurrencyCode(result.getCurrencyCode());
                    calcDto.setProductEstimatedUnit(estimatedMap.get(result.getProductEstimatedUnit()));
                    calcDto.setProductEstimatedTime(result.getProductEstimatedTime());
                    ProductGroup pg = pgMap.get(result.getGroupId() + "");
                    if (pg != null) {
                        calcDto.setGroupName(pg.getParentId() == 1 ? "海运" : (pg.getParentId() == 6 ? "空运" : "速递"));
                    }
                    results.put(result.getQuotationId() + "", calcDto);
                }
                ServiceFeeDto feeDto = new ServiceFeeDto();
                feeDto.setAmount(result.getAmount());
                feeDto.setFeeTypeName(feeTypeMap.get(result.getFeeTypeId() + "").getName());
                feeDto.setServiceUid(result.getServiceUid());
                feeDto.setCurrencyCode(result.getCurrencyCode());
                feeDto.setServiceName(result.getServiceName());
                if (result.isOptional()) {
                    calcDto.getOptionalServices().add(feeDto);
                } else {
                    calcDto.getNeedServices().add(feeDto);
                    calcDto.setTotalAmount(calcDto.getTotalAmount().add(feeDto.getAmount()));
                }
            }
            results.values().forEach(dtos::add);
        }
        Response resp = new Response();
        resp.setData(dtos);
        return resp;
    }
}
